package com.tools.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

@Configuration
@EnableCaching
public class RedisCacheConfig {

    // 注入已配置的ObjectMapper（包含Java 8日期时间类型支持）
    private final ObjectMapper objectMapper;
    
    public RedisCacheConfig(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
        // 使用已配置的ObjectMapper创建GenericJackson2JsonRedisSerializer，支持Java 8日期时间类型
        GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);
        
        // 配置序列化方式（防止缓存数据乱码）
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10)) // 默认过期时间
                .serializeKeysWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(new StringRedisSerializer())) // 键序列化
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(jsonSerializer)) // 值序列化
                .disableCachingNullValues(); // 不缓存 null 值

        // 对特定缓存名称单独配置（如 "users" 缓存过期时间 30 分钟）
        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .withCacheConfiguration("users",
                        config.entryTtl(Duration.ofMinutes(30)))
                .build();
    }
}
